package com.viroyal.monitorlib;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import com.google.gson.Gson;
import com.suntiago.baseui.utils.log.Slog;
import com.viroyal.monitorlib.entity.UpdateS;
import com.viroyal.monitorlib.entity.UploadRes;
import com.viroyal.monitorlib.entity.UploadTable;
import com.viroyal.monitorlib.entity.rx.RxInstall;
import com.viroyal.monitorlib.entity.rx.UpdateRes;
import com.viroyal.monitorlib.network.Api;
import com.viroyal.monitorlib.network.BaseRspObserver;
import com.viroyal.monitorlib.network.UpdateApi;
import com.viroyal.monitorlib.network.rsp.FileUploadResponse;
import com.viroyal.monitorlib.utils.AppUtils;
import com.viroyal.monitorlib.utils.FileUtils;

import org.kymjs.kjframe.KJDB;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Properties;

import io.deepstream.ConfigOptions;
import io.deepstream.ConnectionState;
import io.deepstream.ConnectionStateListener;
import io.deepstream.DeepstreamClient;
import io.deepstream.DeepstreamFactory;
import io.deepstream.DeepstreamRuntimeErrorHandler;
import io.deepstream.Event;
import io.deepstream.EventListener;
import io.deepstream.Topic;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * Created by zy on 2017/11/17.
 */
@Deprecated
public class DeepStem implements UpdateSHelper.Callback {
    private static final String TAG = "DeepStem";
    private DeepstreamClient mClient;


    UpdateSHelper mUpdateSHelper;

    Context mContext;

    public DeepStem(Context context) {
        mContext = context;
        mUpdateSHelper = new UpdateSHelper(this, mContext);
    }

    public void connect() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (mClient == null) {
                    Slog.d(TAG, "run  []mClient == null");
                }
                if (mClient != null) {
                    Slog.d(TAG, "run  []:" + mClient.getConnectionState().name());
//                    mClient.close();
                }
                try {

                    String ap = Api.get().getApiUPDATE();
                    Slog.d(TAG, "run  [getApiUPDATE]:" + ap);

                    Properties options = new Properties();
                    options.put(ConfigOptions.MAX_RECONNECT_ATTEMPTS, 1000);
                    options.put(ConfigOptions.MAX_RECONNECT_INTERVAL, 60 * 1000);

                    DeepstreamFactory factory = DeepstreamFactory.getInstance();
                    mClient = factory.getClient(ap, options);


//                    mClient = new DeepstreamClient(ap);
                    mClient.setRuntimeErrorHandler(new DeepstreamRuntimeErrorHandler() {
                        @Override
                        public void onException(Topic topic, Event event, String s) {
                            Slog.e(TAG, s);
//                            mClient.close();
                        }
                    });

                    mClient.addConnectionChangeListener(new ConnectionStateListener() {

                        @Override
                        public void connectionStateChanged(ConnectionState arg0) {
                            if (arg0 == ConnectionState.CLOSED) {
                                Slog.d(TAG, "connect changed:" + arg0);
//                                mClient.close();
                            }
                        }
                    });


                    Slog.d(TAG, "start login");
                    mClient.login();
                    String macAddress = Api.get().getDeviceId(mContext);
                    Slog.d(TAG, "run  []macAddress :" + macAddress);
                    mClient.event.subscribe("server-req-" + macAddress, new EventListener() {
                        @Override
                        public void onEvent(String s, Object o) {
                            Slog.d(TAG, "s=" + s + " o=" + o.toString());
                            //收到更新的消息
                            try {
                                mUpdateSHelper.addS(new Gson().fromJson(o.toString(), UpdateS.class));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                    });

                    Slog.d(TAG, "end login");
                    //ds.event.emit( "app", "My first ever event!" );
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void receive() {


    }

    public void send(String a) {
        Slog.d(TAG, "send  123 [a]:" + a);
        mClient.event.emit("client-req", a);
    }

    //返回安装操作执行完成
    public void updateRes(String pkg_name, int status) {
        UpdateRes res = mUpdateSHelper.resByPkgName(pkg_name);
        if (res != null) {
            res.status = status;
            send(res.toString());
        }
    }

    //发送命令执行完成回复
    public void updateResUpload(String id, String action, String file_url, String pkg_name) {
        UploadRes uploadRes = new UploadRes(mContext, id, action, file_url, pkg_name);
        if (uploadRes != null) {
            send(uploadRes.toString());
        }
    }

    public void simulateUpdate() {
//        UpdateS updateS = new UpdateS().simlulate();
//        mUpdateSHelper.addS(updateS);
    }

    public void disConnect() {

    }

    @Override
    public void handleNew(UpdateS updateS) {
        Slog.d(TAG, "handleNew  [updateS]:" + updateS.toString());
        if ("install".equals(updateS.action)) {
            //安装的命令
//            if (!AppUtils.isAccessibilitySettingsOn(mContext)) {
//                updateRes(updateS.pkg_name, 3);
//                Slog.d(TAG, "handleNew  [updateS]: isAccessibilitySettingsOn " + false);
//                return;
//            }
            PackageInfo packageInfo = AppUtils.getPackageInfo(mContext, updateS.pkg_name);
            if (packageInfo != null && packageInfo.versionCode >= updateS.version_code) {
                //已经安装过了
                updateRes(updateS.pkg_name, 4);
            } else {
                //需要更新
                if (TextUtils.isEmpty(updateS.url)) {
                    //下载地址为空
                    updateRes(updateS.pkg_name, 5);
                    return;
                } else {
                    //需要卸载
                    if (updateS.uninstall == 1 && AppUtils.isAppInstalled(mContext, updateS.pkg_name)) {
                        //先执行卸载操作
                        AppModel.get().uninstall(updateS.pkg_name);
                        return;
                    }
                }
                AppModel.get().download(updateS.url, updateS.pkg_name);
            }
        } else if ("capture".equals(updateS.action)) {
            //截图命令
            Intent capture = new Intent("com.viroyal.permission.capture");
            capture.putExtra("id", updateS.id + "");
            mContext.sendBroadcast(capture);
        }
    }

    public void apkInstalled(RxInstall rxInstall) {
        if (rxInstall.action.equals("install")) {
            if (rxInstall.success) {
                updateRes(rxInstall.pkg_name, 1);
            }
        } else if (rxInstall.action.equals("uninstall")) {
            //卸载成功，重新开始安装。
            if (rxInstall.success) {
                mUpdateSHelper.unstalled(rxInstall.pkg_name);
            }
        }
    }

    public void hostChange() {
        Slog.d(TAG, "hostChange  []:");
        if (mClient != null) {
            mClient.close();
        }
        connect();
    }


    public void checkCompress1(String filepath) {
        Bitmap bit = BitmapFactory.decodeFile(filepath);

        FileOutputStream fos;
        try {
            // 判断手机设备是否有SD卡
            boolean isHasSDCard = Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED);
            if (isHasSDCard) {
                // SD卡根目录
                File file = new File(filepath);
                fos = new FileOutputStream(file);
            } else
                throw new Exception("创建文件失败!");

            bit.compress(Bitmap.CompressFormat.PNG, 50, fos);

            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void checkCompress(String filepath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        Bitmap bm = BitmapFactory.decodeFile(filepath, options);

        Slog.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)
                + "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());
        FileOutputStream fos;
        try {
            // 判断手机设备是否有SD卡
            boolean isHasSDCard = Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED);
            if (isHasSDCard) {
                // SD卡根目录
                File sdRoot = Environment.getExternalStorageDirectory();
                File file = new File(filepath);
                fos = new FileOutputStream(file);
            } else
                throw new Exception("创建文件失败!");

            bm.compress(Bitmap.CompressFormat.PNG, 90, fos);

            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void upload(final String sid, String filepath, final String pkgName, final String action) {
        if (action.equals("capture")) {
            checkCompress(filepath);
        }
        Slog.d(TAG, "upload  [id, filepath, pkgName, action]:");
        File file = new File(filepath);
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        Api.get().getApi(UpdateApi.class)
                .uploadFile(Api.get().getSchoolId(),Api.get().getDeviceId(mContext),action, body)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BaseRspObserver<FileUploadResponse>(FileUploadResponse.class, new
                        Action1<FileUploadResponse>() {
                            @Override
                            public void call(FileUploadResponse response) {
                                Slog.d(TAG, "upload call  [response]:" + response.toString());
                                if (response.error_code == 1000) {
                                    updateResUpload(sid, action, Api.get().getApi() +
                                            "/upload/" + response.extra, pkgName);
                                    List<UploadTable> l = KJDB.getDefaultInstance().findAllByWhere(
                                            UploadTable.class, "local_path = \"" + filepath + "\"");
                                    if (l.size() > 0) {
                                        UploadTable s = l.get(0);
                                        s.update_time = System.currentTimeMillis();
                                        s.status = 1;
                                    }
                                    deleteCache();
                                } else {
                                    Slog.e(TAG, "call:FileUploadResponse error ");
                                }
                            }
                        }));
    }

    private void deleteCache() {
        List<UploadTable> list = KJDB.getDefaultInstance().findAllByWhere(UploadTable.class,
                "status = 1 AND update_time < " + (System.currentTimeMillis() - 1000 * 60 * 60 * 24));
        if (list != null && list.size() > 0) {
            for (UploadTable uploadTable : list) {
                FileUtils.delFile(uploadTable.local_path);
                KJDB.getDefaultInstance().delete(uploadTable);
            }
        }

    }
}
